import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class LinkedListVSArrayList {
	private int[] dataSizeList = { 100, 500, 750, 875, 1000, 10000, 100000,
			1000000 };

	public static void main(String[] args) {
		LinkedListVSArrayList testEngine = new LinkedListVSArrayList();
		testEngine.test(true);
		testEngine.test(false);
	}

	private void test(boolean warmUp) {
		if (warmUp) {
			System.out.println("WARMING UP...");
		}

		for (Integer dataSize : dataSizeList) {
			double arrayListTime = 0;
			double linkedListTime = 0;

			int cycleCount = dataSize / 10;
			int testSuiteSize = 1000000 / dataSize;

			for (int i = 0; i < testSuiteSize; i++) {
				if (warmUp && dataSize == 1000000)
					return;

				ArrayList<Object> arrayList = new ArrayList<>();
				fillList(arrayList, dataSize);
				LinkedList<Object> linkedList = new LinkedList<>();
				fillList(linkedList, dataSize);

				int[] position = new int[cycleCount];
				Object[] data = new Object[cycleCount];
				for (int k = 0; k < cycleCount; k++) {
					position[k] = (int) (Math.random() * dataSize);
					data[k] = new Object();
				}

				long t = System.nanoTime();
				for (int j = 0; j < cycleCount; j++) {
					arrayList.add(position[j], data[j]);
				}
				arrayListTime += System.nanoTime() - t;

				t = System.nanoTime();
				for (int j = 0; j < cycleCount; j++) {
					linkedList.add(position[j], data[j]);
				}
				linkedListTime += System.nanoTime() - t;
			}
			arrayListTime /= testSuiteSize * cycleCount;
			linkedListTime /= testSuiteSize * cycleCount;

			if (!warmUp) {
				System.out.printf(
						"DATASET: %d\t\tAL: %.3f mcrs\t\tLL: %.3f mcrs\n",
						dataSize, arrayListTime / 1000, linkedListTime / 1000);
			}
		}
	}

	private void fillList(List<Object> list, int dataSize) {
		for (int i = 0; i < dataSize; i++) {
			list.add(new Object());
		}
	}
}
